using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text.Json;
using OracleInternal.Json.Common;
using OracleInternal.Json.Sql;

namespace OracleInternal.Json.Binary
{
	internal abstract class OracleJsonGenerator : IOracleJsonGenerator
	{
		public abstract IOracleJsonGenerator WriteStartObject();

		public abstract IOracleJsonGenerator WriteStartArray();

		public abstract IOracleJsonGenerator WriteKey(string key);

		public abstract IOracleJsonGenerator Write(decimal value);

		public abstract IOracleJsonGenerator Write(BigInteger value);

		public abstract IOracleJsonGenerator Write(string value);

		public abstract IOracleJsonGenerator Write(char[] value, int strLen);

		public abstract IOracleJsonGenerator Write(int value);

		public abstract IOracleJsonGenerator Write(long value);

		public abstract IOracleJsonGenerator Write(double value);

		public abstract IOracleJsonGenerator Write(float value);

		public abstract IOracleJsonGenerator Write(bool value);

		public abstract IOracleJsonGenerator Write(DateTime value);

		public abstract IOracleJsonGenerator Write(string name, DateTime value);

		public abstract IOracleJsonGenerator Write(Period value);

		public abstract IOracleJsonGenerator Write(TimeSpan value);

		public abstract IOracleJsonGenerator Write(byte[] value);

		public abstract IOracleJsonGenerator WriteId(byte[] value);

		public abstract IOracleJsonGenerator Write(string key, byte[] value);

		public abstract IOracleJsonGenerator WriteNull();

		public abstract IOracleJsonGenerator WriteEnd();

		public abstract void Close();

		public abstract void Flush();

		public IOracleJsonGenerator WriteStartObject(string key)
		{
			WriteKey(key);
			WriteStartObject();
			return this;
		}

		public IOracleJsonGenerator WriteStartArray(string key)
		{
			WriteKey(key);
			return WriteStartArray();
		}

		public IOracleJsonGenerator Write(string key, OracleJsonValue value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, string value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, BigInteger value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, decimal value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, int value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, long value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, double value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, float value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, bool value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator WriteNull(string key)
		{
			WriteKey(key);
			return WriteNull();
		}

		public IOracleJsonGenerator Write(string key, Period value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(string key, TimeSpan value)
		{
			WriteKey(key);
			return Write(value);
		}

		public IOracleJsonGenerator Write(OracleJsonValue value)
		{
			WriteOracleJsonValue(value);
			return this;
		}

		public IOracleJsonGenerator WriteParser(Utf8JsonReader parser)
		{
			new JsonpGeneratorWrapper(this).WriteJsonParser(parser);
			return this;
		}

		protected abstract IOracleJsonGenerator WriteBinary(OracleJsonBinary value);

		protected abstract IOracleJsonGenerator WriteDouble(OracleJsonDouble value);

		protected abstract IOracleJsonGenerator WriteFloat(OracleJsonFloat value);

		protected abstract IOracleJsonGenerator WriteOraNumber(OracleJsonDecimal value);

		protected abstract IOracleJsonGenerator WriteTimestamp(OracleJsonTimestamp value);

		protected abstract IOracleJsonGenerator WriteTimestampTZ(OracleJsonTimestampTZ value);

		protected abstract IOracleJsonGenerator WriteDate(OracleJsonDate value);

		protected abstract IOracleJsonGenerator WriteString(OracleJsonString value);

		protected abstract IOracleJsonGenerator WriteIntervalDS(OracleJsonIntervalDS value);

		protected abstract IOracleJsonGenerator WriteIntervalYM(OracleJsonIntervalYM value);

		private void WriteOracleJsonValue(OracleJsonValue value)
		{
			switch (value.GetOracleJsonType())
			{
			case OracleJsonType.OBJECT:
			{
				IOracleJsonObject obj2 = (IOracleJsonObject)value;
				WriteStartObject();
				foreach (KeyValuePair<string, OracleJsonValue> item in obj2)
				{
					WriteKey(item.Key);
					WriteOracleJsonValue(item.Value);
				}
				WriteEnd();
				break;
			}
			case OracleJsonType.ARRAY:
			{
				IOracleJsonArray obj = (IOracleJsonArray)value;
				WriteStartArray();
				foreach (OracleJsonValue item2 in obj)
				{
					WriteOracleJsonValue(item2);
				}
				WriteEnd();
				break;
			}
			case OracleJsonType.BINARY:
				WriteBinary((OracleJsonBinary)value);
				break;
			case OracleJsonType.FLOAT:
				WriteFloat((OracleJsonFloat)value);
				break;
			case OracleJsonType.DOUBLE:
				WriteDouble((OracleJsonDouble)value);
				break;
			case OracleJsonType.DECIMAL:
				WriteOraNumber((OracleJsonDecimal)value);
				break;
			case OracleJsonType.STRING:
				WriteString((OracleJsonString)value);
				break;
			case OracleJsonType.TIMESTAMP:
				WriteTimestamp((OracleJsonTimestamp)value);
				break;
			case OracleJsonType.TIMESTAMPTZ:
				WriteTimestampTZ((OracleJsonTimestampTZ)value);
				break;
			case OracleJsonType.DATE:
				WriteDate((OracleJsonDate)value);
				break;
			case OracleJsonType.INTERVALDS:
				WriteIntervalDS((OracleJsonIntervalDS)value);
				break;
			case OracleJsonType.INTERVALYM:
				WriteIntervalYM((OracleJsonIntervalYM)value);
				break;
			case OracleJsonType.TRUE:
				Write(value: true);
				break;
			case OracleJsonType.FALSE:
				Write(value: false);
				break;
			case OracleJsonType.NULL:
				WriteNull();
				break;
			}
		}
	}
}
